package model

import (
	"ginblog/utils/errmsg"

	"gorm.io/gorm"
)

// Comment 评论结构体
type Comment struct {
	gorm.Model
	UserId    uint   `json:"user_id"`
	ArticleId uint   `json:"article_id"`
	Title     string `gorm:"type:varchar(500);not null;" json:"article_title"`
	Username  string `gorm:"type:varchar(500);not null;" json:"username"`
	Content   string `gorm:"type:varchar(500);not null;" json:"content"`
	Status    int8   `gorm:"type:tinyint;default:2" json:"status"`
}

// AddComment 新增评论
// AddComment 添加评论
// 参数:
//
//	data (*Comment): 待添加的评论数据
//
// 返回值:
//
//	int: 添加评论的结果，返回errmsg.SUCCESS表示成功，返回errmsg.ERROR表示失败
func AddComment(data *Comment) int {
	// 使用db.Create方法将评论数据插入数据库
	err = db.Create(&data).Error
	// 如果插入过程中发生错误
	if err != nil {
		// 返回错误代码
		return errmsg.ERROR
	}
	// 如果插入成功，返回成功代码
	return errmsg.SUCCESS
}

// GetComment 查询单个评论
// GetComment 根据给定的ID获取评论信息。
// 参数:
//
//	id - 评论的唯一标识符。
//
// 返回值:
//
//	Comment - 评论信息结构体。
//	int - 错误代码，表示执行结果的状态。
func GetComment(id int) (Comment, int) {
	// 初始化一个Comment类型的变量comment。
	var comment Comment

	// 使用ID查询数据库中的第一条匹配的评论信息。
	// 如果查询过程中出现错误，将错误信息存储在err中。
	err = db.Where("id = ?", id).First(&comment).Error

	// 检查是否有错误发生。
	if err != nil {
		// 如果有错误，返回当前查询到的评论信息（可能是空的）和错误代码。
		return comment, errmsg.ERROR
	}

	// 如果没有错误，返回查询到的评论信息和成功代码。
	return comment, errmsg.SUCCESS
}

// GetCommentList 后台所有获取评论列表
// GetCommentList 获取评论列表和总数
// 参数:
//
//	pageSize - 每页的评论数量
//	pageNum - 当前页码
//
// 返回值:
//
//	[]Comment - 评论列表
//	int64 - 评论总数
//	int - 错误码
func GetCommentList(pageSize int, pageNum int) ([]Comment, int64, int) {
	// 初始化评论列表和总数变量
	var commentList []Comment
	var total int64

	// 查询评论列表并计算总数
	db.Find(&commentList).Count(&total)

	// 分页查询评论，包括关联的文章标题和用户信息
	err = db.Model(&commentList).Limit(pageSize).Offset((pageNum - 1) * pageSize).Order("Created_At DESC").Select("comment.id, article.title,user_id,article_id, user.username, comment.content, comment.status,comment.created_at,comment.deleted_at").Joins("LEFT JOIN article ON comment.article_id = article.id").Joins("LEFT JOIN user ON comment.user_id = user.id").Scan(&commentList).Error

	// 如果查询出错，返回评论列表，错误码
	if err != nil {
		return commentList, 0, errmsg.ERROR
	}

	// 返回评论列表，总数，成功码
	return commentList, total, errmsg.SUCCESS
}

// GetCommentCount 获取评论数量
// GetCommentCount 根据文章ID获取已批准评论的数量
// 参数:
//
//	id - 文章的ID
//
// 返回值:
//
//	评论的数量
func GetCommentCount(id int) int64 {
	// 定义一个Comment类型的变量comment，用于查询评论信息
	var comment Comment
	// 定义一个int64类型的变量total，用于存储评论数量
	var total int64

	// 使用db.Find(&comment)来查询评论表中符合条件的记录
	// .Where("article_id = ?", id) 指定查询条件为文章ID等于传入的id
	// .Where("status = ?", 1) 指定查询条件为评论状态为已批准（status=1）
	// .Count(&total) 统计满足上述条件的评论数量，并将结果存入total变量
	db.Find(&comment).Where("article_id = ?", id).Where("status = ?", 1).Count(&total)

	// 返回评论数量
	return total
}

// GetCommentListFront 展示页面获取评论列表
// GetCommentListFront 获取前端评论列表
// 该函数根据文章ID、页面大小和页码返回评论列表、总记录数和错误代码
// 参数:
//
//	id - 文章ID
//	pageSize - 页面大小
//	pageNum - 页码
//
// 返回值:
//
//	[]Comment - 评论列表
//	int64 - 总记录数
//	int - 错误代码
func GetCommentListFront(id int, pageSize int, pageNum int) ([]Comment, int64, int) {
	var commentList []Comment
	var total int64

	// 计算总记录数
	db.Find(&Comment{}).Where("article_id = ?", id).Where("status = ?", 1).Count(&total)

	// 查询评论列表
	err = db.Model(&Comment{}).Limit(pageSize).Offset((pageNum-1)*pageSize).Order("Created_At DESC").Select("comment.id, article.title, user_id, article_id, user.username, comment.content, comment.status,comment.created_at,comment.deleted_at").Joins("LEFT JOIN article ON comment.article_id = article.id").Joins("LEFT JOIN user ON comment.user_id = user.id").Where("article_id = ?",
		id).Where("status = ?", 1).Scan(&commentList).Error

	// 如果发生错误，返回评论列表、总记录数0和错误代码
	if err != nil {
		return commentList, 0, errmsg.ERROR
	}

	// 返回评论列表、总记录数和成功代码
	return commentList, total, errmsg.SUCCESS
}

// 编辑评论（暂不允许编辑评论）

// DeleteComment 删除评论
// DeleteComment deletes a comment based on the provided ID.
// Parameter id: The unique identifier of the comment to be deleted.
// Return value: Returns the result of the deletion operation. Returns errmsg.SUCCESS if the deletion is successful, otherwise returns errmsg.ERROR.
func DeleteComment(id uint) int {
	// Initialize a Comment type variable to store the comment information to be deleted.
	var comment Comment
	// Use the ID to query and delete the comment in the database, and check for errors.
	err = db.Where("id = ?", id).Delete(&comment).Error
	// If an error occurs during the deletion process, return errmsg.ERROR to indicate the deletion failed.
	if err != nil {
		return errmsg.ERROR
	}
	// If the deletion is successful, return errmsg.SUCCESS to indicate the deletion succeeded.
	return errmsg.SUCCESS
}

// CheckComment 通过评论
// CheckComment 更新评论的状态，并增加文章的评论计数。
// 参数:
//
//	id - 评论的数据库主键ID。
//	data - 包含要更新的评论状态信息的指针。
//
// 返回值:
//
//	更新操作的结果状态码。
func CheckComment(id int, data *Comment) int {
	// 初始化一个Comment结构体变量用于存储查询到的评论数据。
	var comment Comment
	// 初始化一个Comment结构体变量用于接收更新后的评论数据。
	var res Comment
	// 初始化一个Article结构体变量用于更新文章的评论计数。
	var article Article

	// 创建一个map用于存储要更新的评论状态。
	var maps = make(map[string]interface{})
	// 将要更新的状态字段添加到map中。
	maps["status"] = data.Status

	// 使用db.Model更新数据库中ID为$id$的评论的状态字段，然后获取更新后的评论数据。
	err = db.Model(&comment).Where("id = ?", id).Updates(maps).First(&res).Error
	// 更新对应文章的评论计数，使用gorm.Expr执行SQL表达式增加评论计数。
	db.Model(&article).Where("id = ?", res.ArticleId).UpdateColumn("comment_count", gorm.Expr("comment_count + ?", 1))

	// 如果更新操作中发生错误，则返回错误码。
	if err != nil {
		return errmsg.ERROR
	}
	// 如果更新操作成功，则返回成功码。
	return errmsg.SUCCESS
}

// UncheckComment 撤下评论
// UncheckComment 用于更新评论的状态，并减少文章的评论计数。
// 参数 id 是需要更新的评论的ID。
// 参数 data 包含新的评论状态信息。
// 返回 int 类型的错误代码，表示操作是否成功。
func UncheckComment(id int, data *Comment) int {
	// 初始化一个 Comment 实例，用于后续的数据库操作。
	var comment Comment
	// 初始化一个 Comment 实例，用于接收数据库更新操作后的结果。
	var res Comment
	// 初始化一个 Article 实例，用于后续减少文章评论计数的操作。
	var article Article
	// 创建一个 map，用于存储要更新的评论状态。
	var maps = make(map[string]interface{})
	// 设置要更新的评论状态。
	maps["status"] = data.Status

	// 使用 db.Model 更新指定 ID 的评论状态，并获取更新后的评论信息。
	// 如果存在错误，将错误信息返回。
	err = db.Model(&comment).Where("id = ?", id).Updates(maps).First(&res).Error
	// 减少评论所属文章的评论计数。
	db.Model(&article).Where("id = ?", res.ArticleId).UpdateColumn("comment_count", gorm.Expr("comment_count - ?", 1))
	// 如果有错误发生，返回错误代码。
	if err != nil {
		return errmsg.ERROR
	}
	// 如果操作成功，返回成功代码。
	return errmsg.SUCCESS
}
